iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 22
1

這篇要探討在實作Testing上,我們的會員管理系統是利用Spring Boot,因此就是直接導入Spring Boot Test
下列出Login部分的Unit Test

package com.poyu.practice.unit.service;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

import java.util.Optional;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;

import com.poyu.mms.MemberManagerSystemApplication;
import com.poyu.mms.dao.ITbUserRepository;
import com.poyu.mms.entity.po.TbUser;
import com.poyu.mms.entity.vo.UserVo;
import com.poyu.mms.service.ILoginService;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MemberManagerSystemApplication.class)
public class LoginServiceTest {

	@Autowired
	private ILoginService loginService;

	@MockBean
	private ITbUserRepository userRepository;

	@Before
	public void setup() {
	}

	@Test
	public void login() throws Exception {
		TbUser user = new TbUser("tester", "1234");
		when(userRepository.findByAccount("tester")).thenReturn(Optional.of(user));

		UserVo userVo = new UserVo();
		userVo.setAccount("tester");
		userVo.setPwd("1234");
		// 正確帳號密碼
		assertEquals(user, loginService.login(userVo).get());

		// 錯誤帳號密碼
		userVo.setPwd("4321");
		assertEquals(null, loginService.login(userVo));
	}
}

裡面有關Spring的Annotation部分我就不多說了,關注在Mock上,Mock是一種Test Double

什麼是Test Double測試替身?

先介紹兩個術語:

  • SUT(System Under Test) :待測程式,往往就是我們的Class,包含Controller、Service、Dao....
  • DOC(Depend on Component):相依元件,又稱做合作者Collaborator,就是我們執行程式時會用到的元件,常常也是測試替身想要替換掉的部分

我們在做測試的時候,SUT就是我們要測試的程式,但常常會有對應到的元件會相依,也就是DOC,例如上方單元測試的程式碼,我們要測試登入我們系統的Service是否正確,登入的Service就是我們的SUT,而UserRepository就是我們的相依物件DOC,主要負責撈取DB的資料

那我們在針對Service做單元測試的時候,其實並不需要確認DB連線與資料的部分,因此我們可以將UserRepository回傳的內容固定,就是利用Test Double概念,如此一來就可以很單一單純的測試service的部分了

由此可知,Test Double測試替身,就是將相依的物件替身化,不會有效能、錯誤等等的其他因素影響本體,讓SUT可以更簡單更單純的測試
https://ithelp.ithome.com.tw/upload/images/20191008/20111916BpS3kD3fAu.png
圖片來源:XUnit Test Patterns

5 Types Test Double

https://ithelp.ithome.com.tw/upload/images/20191008/20111916UkZlYTSIBK.png
圖片來源:XUnit Test Patterns

  • Dummy Object
    • 有些時候會呼叫API,需要填物參數,但是我們知道那個參數完全不會被用到,單純是為了滿足編譯用的,不存在任何方法
  • Test Stub
    • 回傳固定值,讓每次呼叫此方法得到的回傳都相同,算是hard code的物件,不會依照測試情況改變
    • 適用情境:DOC無法使用或是速度太慢
  • Test Spy
    • Test Stub的進階版,主要多了紀錄的功能,可以紀錄怎麼被呼叫的、呼叫次數以及是否正確
    • 是真實的物件,只是取代物件中的某個方法
  • Mock Object
    • 與Test Stub類似會有回傳值的設定,但是會針對此回傳值做更深一步的處理與驗證
    • 一個完全替代真實物件的假物件
  • Fake Object
    • 比Test Stub更簡單、輕量,用於滿足介面

參考資料、延伸閱讀:

下集預告:實作分享 - Docker


上一篇
實作分享 - GitHub
下一篇
實作分享 - Docker
系列文
後端功城獅30天DevOps探討挑戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言